iT邦幫忙

2022 iThome 鐵人賽

DAY 3
2
Modern Web

一次打破 React 常見的學習門檻與觀念誤解系列 第 3

[Day 03] React 開發環境建置的門檻

  • 分享至 

  • xImage
  •  

過去有很長一段時間中,開發環境的建置都被視為學習 React 的首要最大難關。由於 React 從非常早期的版本就已經擁抱 transpiler 與 moudle bundler 等現代化的前端技術作為預設的開發環境選項,並且當時並沒有提供官方的開發環境建置工具,因此你必須自己手把手的去設定 Babel、Webpack 的所有細節才能建立一個完善的 React 開發環境。

這其實也是 React 生態圈一直以來的一個缺點:比起 Vue 核心團隊對於開發者極其友善且用心的一條龍周邊工具,React 的核心維護團隊更專注於 React 本身的設計思維、底層實現以及 API 的改善和演進,而相對比較沒有投入太多的心力在打造生態圈中的周邊工具,這也跟 React 定位本身只是 「管理 UI 的函式庫」有關。因此你會看到 React 生態圈中不僅是開發環境建置工具,像是 router、Redux 等熱門的解決方案也都不是由 React 的核心團隊所開發的,而是生態圈中的社群志願者們所打造並維護。


Create React App 方案

所幸 React 核心維護團隊也意識到「開發環境建置工具」是攸關 React 這項技術是否能順利的入門的重要門檻,並且手把手設定有其相當的難度,因此從 2016 年時開始著手推出官方的工具 create-react-app。隨著時間的推移這個工具也不斷的改善並推廣,時至今日已經是一個相當方便且成熟的方案,它能夠讓開發者一鍵的快速建立一個絕大多數情形都可以直接適用的 React 開發環境。

圖片來源:https://create-react-app.dev/docs/getting-started

圖片來源:https://create-react-app.dev/docs/getting-started

而 Create React App 也有專門的官網以及文件提供手把手的使用教學,非常推薦,可以參考此處:https://create-react-app.dev/docs/getting-started

此處我們就不做太細節的介紹了,自行參考官方文件應該就非常夠用。

不過由於它將內建的的 Babel、Webpack 等細節設定都封裝並隱藏起來,因此雖然大多專案的需求下你都可以直接使用它預設的配置,但當你有比較複雜的客製化需求時就會遇到一些限制。因此當你遇到複雜且有高度客製化建置需求的 React 專案時,還是可以考慮自己手動建置開發環境以換取最大的自由度與彈性。


手動建置環境方案

當專案建置環境有比較客製化的需求時,或為了真正搞懂 React 建置環境的細節,仍然值得去研究並瞭解要如何自己手把手的建立 React 開發環境。當然如果我們要手把手的從零完全教學的話可能寫完整個鐵人賽三十篇都還不夠,因此這裡主要會先點出 React 開發環境的必須元素以及為什麼我們需要它們,至於細節的設定方法網路上有非常多的學習資源可以參考。

React 開發環境建置的必要條件

在嘗試自己動手建置前當然是要先了解 React 開發環境哪些需求是必須要滿足的:

  • JSX transformer

    在絕大多數情況下,我們都會使用 JSX 語法來進行 React 的開發,因此將 JSX 語法轉換成瀏覽器能夠執行的普通 JS 語法就幾乎成了必要的需求。通常有兩種方式可以做到這件事情:事前靜態轉換,以及 runtime 即時的轉換

    • 以 transpiler 進行事前靜態轉換
      • 也就是在開發階段就以專用的轉換工具來將包含 JSX 語法的程式碼轉換成普通的 JS 程式碼,然後瀏覽器實際上就直接吃已經事先轉換好的版本來執行。最主流的 transpiler 選擇像是 Babel 或是 TypeScript 都有支援 JSX 的轉換功能。這也是我們通常會在開發環境採用的預設方案。並且由於效能考量,這個方式在 production build 時有其必要性
      • 以最常採用的 babel 為例,我們會需要 @babel/plugin-transform-react-jsx 這個 plugin 來幫我們做 JSX 的轉換,而我們通常會直接使用已經包含這個 plugin 的 @babel/preset-react 來設定在 babel config 當中
    • 以 CDN 作 runtime 的即時轉換
      • 直接在瀏覽器中讀取尚未被轉換的 JSX 程式碼,並依靠 runtime transpiler 即時的翻譯來轉換成普通 JS

      • 例如 babel 有提供 runtime 版本的 standalone,可以作為 CDN 直接引入。只要在包含 JSX 語法的 <script> 標籤上標注 type="text/jsx",babel runtime 就會自動即時將其 JSX 語法進行轉換後再執行:

        <!DOCTYPE html>
        <html>
          <body>
            <div id="app"></div>
            <!-- 引入 React -->
            <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
            <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
            <!-- 引入 Babel runtime -->
            <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
            <script type="text/jsx">
              const root = ReactDOM.createRoot(document.querySelector('#app'));
              // 可以直接在這裡寫 JSX 語法,runtime babel 會即時在瀏覽器端即時轉換後才執行
              root.render(<h1>Hello, world!</h1>);
            </script>
          </body>
        </html>
        
      • 這樣做等同於每次瀏覽器在 JSX 相關的程式執行前都必須花費時間與效能先進行完即時的轉換後,才能開始運行,因此龐大且複雜的應用程式場景時可能有嚴重的效能隱憂

      • 因此非常不建議以這種做法來作為正式的本地開發環境,更完全不應該用於 production build。通常會這樣做是在快速實作一段純演示性質的程式程式的時候才比較合適,例如:在 JSFiddle、codepen 上快速建立一個 React 範例

  • 支援 ES6+ 語法

    除了 JSX 語法之外,在 React 官方或社群推薦的寫法 best practice 中也處處可見使用到較新的 ES6+ 語法,像是陣列解構、物件解構、spread、rest、arrow function…等等,而這些語法仍然會面臨較老舊瀏覽器的向下相容問題

    • 依靠使用者瀏覽器本身原生支援
      • 當然,如果專案本來就完全不打算支援較老舊的瀏覽器,或是也沒有使用到一些更新更潮的語法的話,也可以選擇不處理特別這個問題,讓這些語法在使用者的瀏覽器上直接執行。不過由於通常我們難以控制使用者所使用的瀏覽器種類或版本,時至今日,針對這些近年較新的 ES 語法進行向下相容的轉換仍然有其一定的必要性
    • 以 transpiler 轉換向下相容
      • 如果希望夠過向下相容的轉換來保證能在更多的瀏覽器上執行你的程式碼的話,transpiler 仍然是一個目前推薦的解決方案。如果你使用 babel 的話,通常我們會使用官方已經套裝好的成熟 presets @babel/preset-env,裡面已經內置好所有常見的 ES6+ 語法轉換功能,並且你也可以透過指定目標的瀏覽器支援範圍,來讓他動態的決定哪些語法需要轉換而哪些可以不用
  • 支援 ES module

    最後,React 也非常早就擁抱了現代化前端工程中的重要技術:模組化。尤其是在基於 component base 的開發方式下,我們很常會將不同的 component 拆分成不同的檔案,並且互不干擾,只有在有需要時才手動相互引用。因此設置一個可以支援 ES module 的環境也是 React 開發幾乎必須的條件

    • 用 module bundler 打包
      • 雖然 ES module 語法規格在 2015 年的 ES6 時就已經推出了,但是瀏覽器上的實際原生支援是一直到近兩年才開始慢慢實現,並且相關的整合以及應用也還沒有到非常普及,因此大多情況下我們還是會需要 module bundler 工具來幫我們將本地以 ES module 撰寫的 JS 原始碼們的打包成少數的幾隻 JS 檔案,主流的選擇如:WebpackParcel 以及最近非常火紅的 Vite

推薦的手動建置開發環境參考資料


使用基於 React 的進階框架

React 社群中也有更高度封裝且熱門的框架系統,它們通常也已經內建整合了許多進階的開發環境需求,如 Next.jsRemix 等基於 React 的主流框架。不過它們也封裝了許多其他更進階的其它功能與特性,因此會建議先了解並確定之後再評估是否有需要使用到這些框架。


總結

總體來說,我會推薦你優先考慮使用 Create React App 來建立你的開發環境,它已經能滿足絕大多數的專案需求,並且幾乎無痛完成環境設置。當真的有較高的客製化需求時,再考慮自己手建環境,而工具的選擇最主流的應該還是 Babel + Webpack 的組合,不過你也可以根據自己的需求去替換成其它的類似工具。而如果不只是開發環境,而是整個應用程式都有更進階的需求時(例如 Server-side rendering),才會建議考慮選擇如 Next.js 等框架方案。


2024/2 更新 - 實體書平裝版本預購

在經過快要一年的努力後,本系列文的實體書版本推出了~其中新增並補充了許多鐵人賽版本中沒有的脈絡與細節,並以全彩印刷拉滿視覺上的閱讀體驗,現正熱銷中!有興趣的話歡迎參考看看,也歡迎分享給其他有接觸前端的朋友們,非常感謝大家~

《React 思維進化:一次打破常見的觀念誤解,躍升專業前端開發者》

目前首刷的軟精裝版本各大通路已經幾乎都銷售一空,接下來會再刷推出新的平裝版本:

天瓏(平裝版預購):
https://www.tenlong.com.tw/products/9786263337695

博客來(平裝版):
https://www.books.com.tw/products/0010982322

momo(平裝版):
https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=12528845


上一篇
[Day 02] 學好 React 需要的前置基本功
下一篇
[Day 04] DOM 與 Virtual DOM
系列文
一次打破 React 常見的學習門檻與觀念誤解30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言